/**
 * Created by lintao_alex on 2017/11/3.
 */


namespace game{

    import log = egret.log;

    export class StaticDataUtils{

        private static _listCache:Map<any,any[]> = new Map<any,any[]>();

        private static getMapName(dataClass:any):string{
            let mapName:string = egret.getQualifiedClassName(dataClass)
            if(mapName.indexOf('.')>=0){
                let splitList = mapName.split('.');
                mapName = splitList.pop();
            }
            mapName = mapName.charAt(0).toLowerCase() + mapName.substring(1) + 'Map';
            return mapName;
        }

        static getDataById<T>(dataClass:new()=>T, id:number, hint=true):T{
            let map = StaticDataUtils.getDataMap(dataClass)
            let out = map.get(id)
            if(!out && hint){
                let mapName = StaticDataUtils.getMapName(dataClass);
                log(`静态数据缺失 ${mapName} id=${id}`)
            }
            return out;
        }

        static getDataMap<T>(dataClass:new()=>T):Map<number, T>{
            let mapName = StaticDataUtils.getMapName(dataClass);
            let map = StaticData.Instance[mapName];
            return map;
        }

        static getDataByKeys<T>(dataClass:new()=>T, ...KVList:[string, any][]):T{
            let map = StaticDataUtils.getDataMap(dataClass)
            let out =  ArrayUtils.getFromMap(map, ...KVList);
            if(!out){
                // let mapName = StaticDataUtils.getMapName(dataClass);
                // let logContent = `静态数据缺失 ${mapName}`;
                // for(let i=0,len=KVList.length; i<len; i++){
                //     let kv = KVList[i];
                //     logContent += ' '+kv.join('=')
                // }
                // log(logContent);
            }
            return out;
        }
        static getListByKeys<T>(dataClass:new()=>T, ...KVList:[string, any][]):T[]{
            let map = StaticDataUtils.getDataMap(dataClass);
            let out = ArrayUtils.getListFromMap(map, ...KVList);
            return out;
        }

        /**
         * 获取指定静态表所有数据
         * @param dataClass 静态表对象
         */
        static getListAll<T>(dataClass:new()=>T) {
            if(!this._listCache.has(dataClass)){
                this._listCache.set(dataClass,this.getListByKeys(dataClass));
            }
            return this._listCache.get(dataClass) as T[];
        }

        /**
         * 获取静态表所有数据，按特定参数排序
         * @param {{new(): T}} dataClass
         * @param {string} sortParam
         * @param {game.SortType} sortType
         */
        static getListAllBySort<T>(dataClass:new()=>T,sortParam:string,sortType:SortType){
            let list = this.getListAll(dataClass);
            return list.sort((a,b):number=>
            {
                if(sortType == SortType.ASCENDING)return a[sortParam] - b[sortParam];
                return [b][sortParam] - a[sortParam];
            })
        }

        static prepareData(cmpFuc:Function, cmpObj:any, ...cmpArgs){
            let sData = StaticData.Instance
            RES.getResAsync('staticdata_cfg', (dat)=>{
                let inflater = new Zlib.RawInflate(dat)
                let u8 = inflater.decompress();
                let dataSource:IStaticDataList = StaticDataList.decode(u8);
                for(let key in dataSource){
                    let prefix = key.split('List')[0]
                    let mapName = prefix+'Map';
                    let map = sData[mapName];
                    let list = dataSource[key];
                    for(let element of list){
                        map.set(element.id, element)
                    }
                }
                cmpFuc.apply(cmpObj, cmpArgs)
            }, this)
        }

        static getArmyTurnNum(armyId:number){
            let armyList = ArrayUtils.getListFromMap(StaticData.Instance.armyMonsterMap, ['armyId', armyId])
            let result:number = 1;
            for(var i = armyList.length - 1; i >= 0; i--){
                var army = armyList[i];
                if(army.turnId>result){
                    result = army.turnId;
                }
            }
            return result;
        }

        /**
         * 获得每日任务最大活跃度值
         * @return 最高档次静态表记录
         */
        static getMaxTaskProgressNum() {
            let taskProgressList:TaskProgress[] = ArrayUtils.getListFromMap(this.getDataMap(TaskProgress));
            let rtn:TaskProgress = null;
            for (let i = 0; i < taskProgressList.length; i++) {
                let each:TaskProgress = taskProgressList[i];
                if (rtn == null || rtn.num < each.num) {
                    rtn = each;
                }
            }
            return rtn;
        }

        /**
         * 获得当前活跃度能够满足的档次数量
         * @param currAnimate 当前活跃度
         * @return 满足条件的档次数
         */
        static getTaskProgressId(currAnimate:number) {
            let taskProgressList:TaskProgress[] = ArrayUtils.getListFromMap(this.getDataMap(TaskProgress));
            let rtn:number = 0;
            for (let i = 0; i < taskProgressList.length; i++) {
                let each:TaskProgress = taskProgressList[i];
                if (currAnimate >= each.num) {
                    rtn = rtn + 1;
                } else {
                    break;
                }
            }
            return rtn;
        }

        private static _keyToBoss:Map<string,Monster>
        static getBossByArmy(army:Army)
        {
            if(!this._keyToBoss)
            {
                this._keyToBoss = new Map<string,Monster>();
                let armyMap = StaticData.Instance.armyMap;
                armyMap.forEach((value)=>
                {
                    if(value.boss.length)
                        this._keyToBoss.set(value.boss,null);
                },this);

                let monsterMap = StaticData.Instance.monsterMap;
                monsterMap.forEach((value2)=>
                {
                    let tKey = value2.monsterId + "_" + value2.level;
                    if(this._keyToBoss.has(tKey))
                        this._keyToBoss.set(tKey,value2);
                },this);
            }

            if(this._keyToBoss.has(army.boss))
            {
                let returnValue = this._keyToBoss.get(army.boss);
                if(returnValue)return returnValue;
            }
                
            throw  new Error(`army = ${army.id} , boss = ${army.boss},找不到武将形象`);
        }

        static getEnemyCntList(armyId:number, ignoreBack=false){
            let orgList = StaticDataUtils.getListByKeys(ArmyMonster, ['armyId', armyId]);
            let map = new Map<number, EnemyCnt>();
            for(let enemy of orgList){
                if(ignoreBack && enemy.posId>1000) continue;
                let obj = map.get(enemy.monsterId)
                if(!obj){
                    obj = {monsterId:enemy.monsterId, num:1}
                    map.set(enemy.monsterId, obj)
                }else{
                    obj.num ++;
                }
            }
            let out:EnemyCnt[] = [];
            map.forEach((cntObj)=>{
                out.push(cntObj);
            })
            return out;
        }

        static getWorldTaskTurnMaxPos(turn:number){
            let posList = StaticDataUtils.getListByKeys(WorldTask, ['turn', turn])
            let result = -1;
            for(let task of posList){
                if(task.pos>result){
                    result = task.pos;
                }
            }
            return result;
        }

        static getArmyByOpenFunction(key:string):Army|null{
            let map = this.getDataMap(Army);
            let out:Army;
            map.forEach((check)=>{
                if(!out && check.dropStr.indexOf(key)>=0){
                    out = check;
                }
            },this)
            return out;
        }
    }

    export interface EnemyCnt{
        isHero?:boolean;
        monsterId:number;
        num:number;
    }

    export enum SortType{
        ASCENDING,
        DESCENDING
    }
}
